package com.candy.candymember.threadInfo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.TaskDecorator;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author suYanLong
 * @version 1.0
 * @date 2023/3/7 16:52
 * @Description 线程间上下文传递 ；https://mp.weixin.qq.com/s/vWZu_pjJIrqHzCyBcM70rg
 */
@Slf4j
public class Test {

    // 手动设置
    public static void handlerAsync() {
        //1. 获取父线程的loginVal
        String loginVal = OauthContext.get();
        log.info("父线程的值：{}", OauthContext.get());
        CompletableFuture.runAsync(() -> {
            //2. 设置子线程的值，复用
            OauthContext.set(loginVal);
            log.info("子线程的值：{}", OauthContext.get());
        });
    }

    // 线程池设置TaskDecorator
    public class ContextTaskDecorator implements TaskDecorator {

        @Override
        public Runnable decorate(Runnable runnable) {
            //获取父线程的loginVal
            String loginVal = OauthContext.get();
            return () -> {
                try {
                    // 将主线程的请求信息，设置到子线程中
                    OauthContext.set(loginVal);
                    // 执行子线程，这一步不要忘了
                    runnable.run();
                } finally {
                    // 线程结束，清空这些信息，否则可能造成内存泄漏
                    OauthContext.clear();
                }
            };
        }

    }

    @Bean("taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
        poolTaskExecutor.setCorePoolSize(11);
        poolTaskExecutor.setMaxPoolSize(11);
        // 设置线程活跃时间（秒）
        poolTaskExecutor.setKeepAliveSeconds(11);
        // 设置队列容量
        poolTaskExecutor.setQueueCapacity(11);
        //设置TaskDecorator，用于解决父子线程间的数据复用
        poolTaskExecutor.setTaskDecorator(new ContextTaskDecorator());
        poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        return poolTaskExecutor;
    }

    public void handlerAsync2() {
        log.info("父线程的用户信息：{}", OauthContext.get());
        //执行异步任务，需要指定的线程池
        CompletableFuture.runAsync(() -> log.info("子线程的用户信息：{}", OauthContext.get()), taskExecutor());
    }

    // InheritableThreadLocal
    private static final InheritableThreadLocal<String> loginValThreadLocal = new InheritableThreadLocal<>();

    // TransmittableThreadLocal

    public static void main(String[] args) throws InterruptedException {
//        OauthContext.set("loginVal");
//        handlerAsync();
        System.out.println("111".equals(null));
        //单一线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        //InheritableThreadLocal存储
        InheritableThreadLocal<String> username = new InheritableThreadLocal<>();
//        InheritableThreadLocal<String> username = new InheritableThreadLocal<>();
        for (int i = 0; i < 10; i++) {
            username.set("公众号：码猿技术专栏—" + i);
            System.out.println(username.get());
            Thread.sleep(3000);
            CompletableFuture.runAsync(() -> System.out.println(username.get()), executorService);
        }

    }

}
